<!DOCTYPE html>
<html lang="zh-cn"><head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    
    <link href="/css/bootstrap.min.css" rel="stylesheet">
    <link href="/css/main.css" rel="stylesheet">

    <link rel="shortcut icon" type="image/x-icon" href="/img/favicon.ico" />

    <title>Go程序的数组声明和初始化 | wiseAI的小站</title>
</head><body><div class="container-fluid">
    <nav class="navbar fixed-top navbar-expand-sm navbar-dark bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand" href="/">
                <img src="/img/favicon.ico" alt="" width="30" height="24" class="d-inline-block align-text-top">
                wiseAI的小站
            </a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/articles/">文章</a>
                    </li>
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/categories/">分类</a>
                    </li>
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/tags/">关键字</a>
                    </li>
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/post/golang/">golang编程</a>
                    </li>
                    
                    <li class="nav-item">
                        <a  class="nav-link"   href="/about/">关于</a>
                    </li>
                    
                </ul>
                <form class="d-flex">
                    <input id="search-query" class="form-control me-2" type="search" placeholder="Search for anything..." aria-label="Search">
                </form>
            </div>
        </div>
    </nav>
</div>




<div id="content">
<div class="container article">
	<h1>Go程序的数组声明和初始化</h1>
	<div class="post-meta">
		<div>
			
			
			By wiseai | 2022-07-26 | 4 minutes
		</div>
		<div class="tags">
			
			<a class="btn btn-light links btn-sm" href="/tags/%E7%BC%96%E7%A8%8B/">编程</a>
			
		</div>
	</div>
	<div>
		<div class="article-post">
			<h1 id="71-声明和初始化">7.1 声明和初始化</h1>
<h2 id="711-概念">7.1.1 概念</h2>
<p>数组是具有相同 <strong>唯一类型</strong> 的一组已编号且长度固定的数据项序列（这是一种同构的数据结构）；这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。数组长度必须是一个常量表达式，并且必须是一个非负整数。数组长度也是数组类型的一部分，所以 <code>[5]int</code> 和 <code>[10]int</code> 是属于不同类型的。数组的编译时值初始化是按照数组顺序完成的（如下）。</p>
<p><strong>注意事项</strong> 如果我们想让数组元素类型为任意类型的话可以使用空接口作为类型（参考 <a href="11.9.md">第 11 章</a>）。当使用值时我们必须先做一个类型判断（参考 <a href="11.3.md">第 11 章</a>）。</p>
<p>数组元素可以通过 <strong>索引</strong>（位置）来读取（或者修改），索引从 <code>0</code> 开始，第一个元素索引为 <code>0</code>，第二个索引为 <code>1</code>，以此类推（数组以 0 开始在所有类 C 语言中是相似的）。元素的数目（也称为长度或者数组大小）必须是固定的并且在声明该数组时就给出（编译时需要知道数组长度以便分配内存）；数组长度最大为 2GB。</p>
<p>声明的格式是：</p>
<pre tabindex="0"><code>var identifier [len]type
</code></pre><p>例如：</p>
<pre tabindex="0"><code>var arr1 [5]int
</code></pre><p>在内存中的结构是：<img src="images/7.1_fig7.1.png?raw=true" alt=""></p>
<p>每个元素是一个整型值，当声明数组时所有的元素都会被自动初始化为默认值 0。</p>
<p><code>arr1</code> 的长度是 5，索引范围从 <code>0</code> 到 <code>len(arr1)-1</code>。</p>
<p>第一个元素是 <code>arr1[0]</code>，第三个元素是 <code>arr1[2]</code>；总体来说索引 <code>i</code> 代表的元素是 <code>arr1[i]</code>，最后一个元素是 <code>arr1[len(arr1)-1]</code>。</p>
<p>对索引项为 <code>i</code> 的数组元素赋值可以这么操作：<code>arr[i] = value</code>，所以数组是 <strong>可变的</strong>。</p>
<p>只有有效的索引可以被使用，当使用等于或者大于 <code>len(arr1)</code> 的索引时：如果编译器可以检测到，会给出索引超限的提示信息；如果检测不到的话编译会通过而运行时会 <code>panic()</code>:（参考<a href="13.0.md">第 13 章</a>）</p>
<pre><code>runtime error: index out of range
</code></pre>
<p>由于索引的存在，遍历数组的方法自然就是使用 <code>for</code> 结构：</p>
<ul>
<li>通过 <code>for</code> 初始化数组项</li>
<li>通过 <code>for</code> 打印数组元素</li>
<li>通过 <code>for</code> 依次处理元素</li>
</ul>
<p>示例 7.1 <a href="examples/chapter_7/for_arrays.go">for_arrays.go</a></p>
<pre tabindex="0"><code>package main
import &#34;fmt&#34;

func main() {
	var arr1 [5]int

	for i:=0; i &lt; len(arr1); i++ {
		arr1[i] = i * 2
	}

	for i:=0; i &lt; len(arr1); i++ {
		fmt.Printf(&#34;Array at index %d is %d\n&#34;, i, arr1[i])
	}
}
</code></pre><p>输出结果：</p>
<pre><code>Array at index 0 is 0
Array at index 1 is 2
Array at index 2 is 4
Array at index 3 is 6
Array at index 4 is 8
</code></pre>
<p><code>for</code> 循环中的条件非常重要：<code>i &lt; len(arr1)</code>，如果写成 <code>i &lt;= len(arr1)</code> 的话会产生越界错误。</p>
<p>IDIOM:</p>
<pre tabindex="0"><code>for i:=0; i &lt; len(arr1); i++｛
	arr1[i] = ...
}
</code></pre><p>也可以使用 for-range 的生成方式：</p>
<p>IDIOM:</p>
<pre tabindex="0"><code>for i,_:= range arr1 {
...
}
</code></pre><p>在这里 <code>i</code> 也是数组的索引。当然这两种 <code>for</code> 结构对于切片（<code>slices</code>）（参考 <a href="07.2.md">第 7 章</a>）来说也同样适用。</p>
<p><strong>问题 7.1</strong> 下面代码段的输出是什么？</p>
<pre tabindex="0"><code>a := [...]string{&#34;a&#34;, &#34;b&#34;, &#34;c&#34;, &#34;d&#34;}
for i := range a {
	fmt.Println(&#34;Array item&#34;, i, &#34;is&#34;, a[i])
}
</code></pre><p>Go 语言中的数组是一种 <strong>值类型</strong>（不像 C/C++ 中是指向首元素的指针），所以可以通过 <code>new()</code> 来创建： <code>var arr1 = new([5]int)</code>。</p>
<p>那么这种方式和 <code>var arr2 [5]int</code> 的区别是什么呢？<code>arr1</code> 的类型是 <code>*[5]int</code>，而 <code>arr2</code> 的类型是 <code>[5]int</code>。</p>
<p>这样的结果就是当把一个数组赋值给另一个时，需要再做一次数组内存的拷贝操作。例如：</p>
<pre tabindex="0"><code>arr2 := *arr1
arr2[2] = 100
</code></pre><p>这样两个数组就有了不同的值，在赋值后修改 <code>arr2</code> 不会对 <code>arr1</code> 生效。</p>
<p>所以在函数中数组作为参数传入时，如 <code>func1(arr2)</code>，会产生一次数组拷贝，<code>func1()</code> 方法不会修改原始的数组 <code>arr2</code>。</p>
<p>如果你想修改原数组，那么 <code>arr2</code> 必须通过 <code>&amp;</code> 操作符以引用方式传过来，例如 <code>func1(&amp;arr2)</code>，下面是一个例子：</p>
<p>示例 7.2 <a href="examples/chapter_7/pointer_array.go">pointer_array.go</a>:</p>
<pre tabindex="0"><code>package main
import &#34;fmt&#34;
func f(a [3]int) { fmt.Println(a) }
func fp(a *[3]int) { fmt.Println(a) }

func main() {
	var ar [3]int
	f(ar) 	// passes a copy of ar
	fp(&amp;ar) // passes a pointer to ar
}
</code></pre><p>输出结果：</p>
<pre><code>[0 0 0]
&amp;[0 0 0]
</code></pre>
<p>另一种方法就是生成数组切片并将其传递给函数（详见<a href="07.1.md">第 7.1.4 节</a>）。</p>
<p><strong>练习</strong></p>
<p>练习7.1：<a href="examples/chapter_7/array_value.go">array_value.go</a>:</p>
<p>证明当数组赋值时，发生了数组内存拷贝。</p>
<p>练习7.2：<a href="examples/chapter_7/for_array.go">for_array.go</a>:</p>
<p>写一个循环并用下标给数组赋值（从 0 到 15）并且将数组打印在屏幕上。</p>
<p>练习7.3：<a href="examples/chapter_7/fibonacci_array.go">fibonacci_array.go</a>:</p>
<p>在<a href="06.6.md">第 6.6 节</a> 我们看到了一个递归计算 Fibonacci 数值的方法。但是通过数组我们可以更快的计算出 Fibonacci 数。完成该方法并打印出前 50 个 Fibonacci 数字。</p>
<h2 id="712-数组常量">7.1.2 数组常量</h2>
<p>如果数组值已经提前知道了，那么可以通过 <strong>数组常量</strong> 的方法来初始化数组，而不用依次使用 <code>[]=</code> 方法（所有的组成元素都有相同的常量语法）。</p>
<p>示例 7.3 <a href="examples/chapter_7/array_literals.go">array_literals.go</a></p>
<pre tabindex="0"><code>package main
import &#34;fmt&#34;

func main() {
	// var arrAge = [5]int{18, 20, 15, 22, 16}
	// var arrLazy = [...]int{5, 6, 7, 8, 22}
	// var arrLazy = []int{5, 6, 7, 8, 22}	//注：初始化得到的实际上是切片slice
	var arrKeyValue = [5]string{3: &#34;Chris&#34;, 4: &#34;Ron&#34;}
	// var arrKeyValue = []string{3: &#34;Chris&#34;, 4: &#34;Ron&#34;}	//注：初始化得到的实际上是切片slice

	for i:=0; i &lt; len(arrKeyValue); i++ {
		fmt.Printf(&#34;Person at %d is %s\n&#34;, i, arrKeyValue[i])
	}
}
</code></pre><p>第一种变化：</p>
<pre tabindex="0"><code>var arrAge = [5]int{18, 20, 15, 22, 16}
</code></pre><p>注意 <code>[5]int</code> 可以从左边起开始忽略：<code>[10]int {1, 2, 3}</code> :这是一个有 10 个元素的数组，除了前三个元素外其他元素都为 <code>0</code>。</p>
<p>第二种变化：</p>
<pre tabindex="0"><code>var arrLazy = [...]int{5, 6, 7, 8, 22}
</code></pre><p><code>...</code> 同样可以忽略，从技术上说它们其实变成了切片。</p>
<p>第三种变化：<code>key: value 语法</code></p>
<pre tabindex="0"><code>var arrKeyValue = [5]string{3: &#34;Chris&#34;, 4: &#34;Ron&#34;}
</code></pre><p>只有索引 3 和 4 被赋予实际的值，其他元素都被设置为空的字符串，所以输出结果为：</p>
<pre><code>Person at 0 is
Person at 1 is
Person at 2 is
Person at 3 is Chris
Person at 4 is Ron
</code></pre>
<p>在这里数组长度同样可以写成 <code>...</code>。</p>
<p>你可以取任意数组常量的地址来作为指向新实例的指针。</p>
<p>示例 7.4 <a href="examples/chapter_7/pointer_array2.go">pointer_array2.go</a></p>
<pre tabindex="0"><code>package main
import &#34;fmt&#34;

func fp(a *[3]int) { fmt.Println(a) }

func main() {
	for i := 0; i &lt; 3; i++ {
		fp(&amp;[3]int{i, i * i, i * i * i})
	}
}
</code></pre><p>输出结果：</p>
<pre tabindex="0"><code>&amp;[0 0 0]
&amp;[1 1 1]
&amp;[2 4 8]
</code></pre><p>几何点（或者数学向量）是一个使用数组的经典例子。为了简化代码通常使用一个别名：</p>
<pre tabindex="0"><code>type Vector3D [3]float32
var vec Vector3D
</code></pre><h2 id="713-多维数组">7.1.3 多维数组</h2>
<p>数组通常是一维的，但是可以用来组装成多维数组，例如：<code>[3][5]int</code>，<code>[2][2][2]float64</code>。</p>
<p>内部数组总是长度相同的。Go 语言的多维数组是矩形式的（唯一的例外是切片的数组，参见<a href="07.2.md">第 7.2.5 节</a>。</p>
<p>示例 7.5 <a href="examples/chapter_7/multidim_array.go">multidim_array.go</a></p>
<pre tabindex="0"><code>package main
const (
	WIDTH  = 1920
	HEIGHT = 1080
)

type pixel int
var screen [WIDTH][HEIGHT]pixel

func main() {
	for y := 0; y &lt; HEIGHT; y++ {
		for x := 0; x &lt; WIDTH; x++ {
			screen[x][y] = 0
		}
	}
}
</code></pre><h2 id="714-将数组传递给函数">7.1.4 将数组传递给函数</h2>
<p>把一个大数组传递给函数会消耗很多内存。有两种方法可以避免这种情况：</p>
<ul>
<li>传递数组的指针</li>
<li>使用数组的切片</li>
</ul>
<p>接下来的例子阐明了第一种方法：</p>
<p>示例 7.6 <a href="examples/chapter_7/array_sum.go">array_sum.go</a></p>
<pre tabindex="0"><code>package main
import &#34;fmt&#34;

func main() {
	array := [3]float64{7.0, 8.5, 9.1}
	x := Sum(&amp;array) // Note the explicit address-of operator
	// to pass a pointer to the array
	fmt.Printf(&#34;The sum of the array is: %f&#34;, x)
}

func Sum(a *[3]float64) (sum float64) {
	for _, v := range a { // derefencing *a to get back to the array is not necessary!
		sum += v
	}
	return
}
</code></pre><p>输出结果：</p>
<pre><code>The sum of the array is: 24.600000
</code></pre>
<p>但这在 Go 中并不常用，通常使用切片（参考 <a href="07.2.md">第 7.2 节</a>）。</p>

		</div>
	</div>
</div>


<div class="container">
    
    <div class="row">
        
        <div class="col-5">
            <a class="page-link link-dark text-end dh" href="/post/golang/2022.07.25-%E5%BA%94%E7%94%A8%E9%97%AD%E5%8C%85%E5%B0%86%E5%87%BD%E6%95%B0%E4%BD%9C%E4%B8%BA%E8%BF%94%E5%9B%9E%E5%80%BC/">
                <h5>前一篇</h5><br>
                Go程序的应用闭包：将函数作为返回值
            </a>            
        </div>
        
        <div class="col-2">
        </div>
        
        <div class="col-5">
            <a class="page-link link-dark text-start dh" href="/post/golang/2022.07.27-%E5%88%87%E7%89%87/">
                <h5>后一篇</h5><br>
                Go程序的切片
            </a>            
        </div>
        
    </div>
    
</div>

        </div><br><br>
<footer class="container">
    <h2>友情链接</h2>
    <hr>
    <nav class="nav nav-pills flex-column flex-sm-row">
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/gnzg/index.html" target="_blank">孤鸟之歌</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/mm/index.html" target="_blank">生成随机字符</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/md/index.html" target="_blank">MarkDown</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://gitee.com/" target="_blank">Gitee</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://github.com/" target="_blank">Github</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.aliyun.com/" target="_blank">阿里云</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://cloud.tencent.com/" target="_blank">腾讯云</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.oschina.net/" target="_blank">OSCHINA开源中国</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://gitee.com/wiseai/the-way-to-go_ZH_CN/blob/master/eBook/directory.md" target="_blank">the way to go</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://topgoer.com/" target="_blank">golang文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://goframe.org/display/gf" target="_blank">GoFrame</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.aliyundrive.com/" target="_blank">阿里云盘</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://cn.vuejs.org/" target="_blank">vue3文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://element-plus.gitee.io/zh-CN/" target="_blank">element-plus文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.runoob.com/vue3/vue3-tutorial.html" target="_blank">vue3菜鸟教程</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://v5.bootcss.com/" target="_blank">bootstrap v5 中文文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.bootstrap.cn/" target="_blank">bootstrap文档</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://caddy2.dengxiaolong.com/docs/" target="_blank">caddy中文教程</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.58pic.com/" target="_blank">千图</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://ifonts.com/" target="_blank">iFonts</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://marketing.qiniu.com/" target="_blank">七牛云</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.ixigua.com/" target="_blank">西瓜视频</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/yugang/index.html" target="_blank">鱼缸计算</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://justcc.mengkang.net/#/" target="_blank">C语言JustCC</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://wiseai.gitee.io/pages/pptist/" target="_blank">PPTist</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="/index.xml" target="_blank">RSS</a>
        
        <a class="flex-sm-fill text-sm-center nav-link links link-dark" href="https://www.kancloud.cn/idcpj/python/418553" target="_blank">参考资料</a>
        
    </nav>

    <div class="copyright text-center">
      <span class="power-by">
        Powered by <a class="links" href="https://gohugo.io" target="_blank">Hugo</a>
    </span>
    <span>|</span>
    <span>
        Theme - <a class="links" href="https://github.com/wiseai-go/blog-hugo" target="_blank">WiseAI</a>
    </span>
    <br>
    <span class="copyright-year">
        &copy;
        
        2017 -
        2023<span>
            陇ICP备15000157号
            
        </span></span>

</div>
</footer>
<script src="/js/bootstrap.bundle.min.js"></script>


</body>
</html>
